package Cluster;

import java.util.ArrayList;
import java.util.List;

import Application.ImageGenerator;
import Application.ReadFileGenerateor;
import MyLoader.MyLoader;
import XmlLoader.FGObjProcess;
import XmlLoader.FGObjectTrajectoryStructure;
import XmlLoader.Position;

public class ClusterBulk {
	
	int clusterID;
	ArrayList<Trajectory> trajList = null;
	Trajectory mainTraj = null;
	int maxLength = -1;
	int typyMainTraj = -1;
	int mergedID = -1;
	
	//cluster range
	int minX = 9999, minY = 9999, maxX = -1, maxY = -1;
	HashClusterRange hcRange = null;
	
	public ClusterBulk (int newID, int typyMainTraj) {
		this.clusterID = newID;
		this.trajList = new ArrayList<Trajectory>();
		this.mainTraj = new Trajectory();
		
		this.typyMainTraj = typyMainTraj;
		this.hcRange = new HashClusterRange();
	}
	
	public void ACT001_insertNewTraj(Trajectory newTraj) {
		this.trajList.add(newTraj);
		if(this.maxLength < newTraj.GET001_length()) {
			this.maxLength = newTraj.GET001_length();
		}
		//this.__001_setMainTraj();
		//this.__002_setRange();
	}
	
	public void ACT002_initialMainTraj(Trajectory main) {
		this.mainTraj = main;
	}
	
	public void ACT003_countMainTraj() {
		switch (this.typyMainTraj) {
			case MainTraj.MAINTRAJ_AVG :
				this.mainTraj = MainTraj.Average(this.trajList, this.maxLength);
			break;
		}
	}
	
	public void ACT004_clearCluster() {
		this.trajList.clear();
		this.maxLength = -1;
		minX = 9999;
		minY = 9999;
		maxX = -1;
		maxY = -1;
	}
	
	public void ACT005_mergeCluster(ClusterBulk cb) {
		int index = 0;
		while(index < cb.GET002_listTraj().size()) {
			//if(!this.isContain(cb.GET002_listTraj().get(index))) {
				this.ACT001_insertNewTraj(cb.GET002_listTraj().get(index));
			//}
			index = index + 1;
		}
		
		this.mergedID = cb.GET005_id();
	}
	
	public void ACT006_show() {
		int index = 0;
		while(index < this.trajList.size()) {
			System.out.print(this.trajList.get(index).GET003_trajID() + " ");
			index = index + 1;
		}
		System.out.println();
	}
	
	public Double ACT007_countMainDirectionAngle(int rangeOfOneClass) {
		double result = 0.0;
		//initial counting array
		int[] listCount = new int[360/rangeOfOneClass];
		int index = 0;
		while(index < listCount.length) {
			listCount[index] = 0;
			index = index + 1;
		}
		//do direction counting
		Vector vStandard = new Vector(0, 0, 0, 1);
		Position pos1 = null, pos2 = null;
		int indexTraj = 0, indexPoint = 0;
		double angle = 0.0;
		while(indexTraj < this.trajList.size()) {
			indexPoint = 0;
			Trajectory traj = this.trajList.get(indexTraj);
			while(indexPoint < traj.GET001_length() - 1) {
				pos1 = traj.GET002_point(indexPoint);
				pos2 = traj.GET002_point(indexPoint + 1);
				Vector vTraj = new Vector(pos1.x, pos1.y, pos2.x - pos1.x, pos1.y - pos2.y);
				angle = vStandard.ACT001_countAngle(vTraj);
				listCount[(int) (angle / rangeOfOneClass)] ++;
				indexPoint = indexPoint + 1;
			}
			indexTraj = indexTraj + 1;
		}
		//get maximum direction range
		int maxValue = 0, maxIndex = 0;
		index = 0;
		while(index < listCount.length) {
			if(listCount[index] > maxValue) {
				maxValue = listCount[index];
				maxIndex = index;
			}
			index = index + 1;
		}
		result = (2 * maxIndex + 1) * rangeOfOneClass / 2;
		return result;
	}
	
	public void ACT008_countDistribution(double mainDirection, int cubeLen, int framewidth, int frameheight) {
		int[][] arrayCount = new int[frameheight/cubeLen][framewidth/cubeLen];
		//initial counting array
		int indexRow = 0, indexCol = 0;
		while(indexRow < arrayCount.length) {
			indexCol = 0;
			while(indexCol < arrayCount[0].length) {
				arrayCount[indexRow][indexCol] = 0;
				indexCol = indexCol + 1;
			}
			indexRow = indexRow + 1;
		}
		//start counting
		int indexTraj = 0, indexPoint = 0;
		Position pos = null;
		while(indexTraj < this.trajList.size()) {
			indexPoint = 0;
			Trajectory traj = this.trajList.get(indexTraj);
			while(indexPoint < traj.GET001_length() - 1) {
				pos = traj.GET002_point(indexPoint);
				arrayCount[pos.x/cubeLen][pos.y/cubeLen] ++;
				indexPoint = indexPoint + 1;
			}
			indexTraj = indexTraj + 1;
		}
		
		for(int i = 0; i < arrayCount.length; i++) {
			for(int j=0; j < arrayCount[0].length; j++) {
				System.out.printf("%3d ", arrayCount[i][j]);
			}
			System.out.println();
		}
		
		//do sampling
		double sampleDir = Vector.ACT002_countUnitVector((mainDirection + 90) % 180);
		System.out.println(sampleDir);
		int indexY = 0, indexX = 0;
		if(sampleDir < 0) {
			//start from leftDown point
			
		}
		else {
			
		}
	}
	
	public boolean isContain(Trajectory newTraj) {
		int index = 0;
		boolean isContain = false;
		while(!isContain && index < this.trajList.size()) {
			if(this.trajList.get(index).GET003_trajID() == newTraj.GET003_trajID()) {
				isContain = true;
			}
			index = index + 1;
		}
		return isContain;
	}
	
	public Trajectory GET001_mainTraj() {
		return this.mainTraj;
	}
	
	public ArrayList<Trajectory> GET002_listTraj() {
		return this.trajList;
	}
	
	public int[] GET003_clusterRange() {
		int[] list = {this.minX, this.minY, this.maxX, this.maxY};
		return list;
	}
	
	public HashClusterRange GET004_hashClusterRange() {
		return this.hcRange;
	}
	
	public int GET005_id() {
		return this.clusterID;
	}
	
	public int GET006_mergeID() {
		return mergedID;
	}
	
	public static void main(String[] args) {
		//generate list trajectory index
		System.out.println("Generate trajectory index file");
		new ReadFileGenerateor().ACT001_genFile(args[0], Integer.parseInt(args[1]), Integer.parseInt(args[2]));
								
		//load trajectory xml data
		System.out.println("Load trajectory xml file");
		FGObjProcess fgObj = new FGObjProcess(args[3]);
		List<String> list_objIndex = fgObj.ACT004_getStringList(args[0]);
		List<FGObjectTrajectoryStructure> list = new MyLoader().ACT001_getListOfObj(args[3], list_objIndex);
	
		//load cluster & count main direction
		//ArrayList<ClusterBulk> listCb = ImageGenerator.GenClusterOneByOneFromFile(list, filePathRead, filePathWrite, length, width, background)
	}
}
